![]() | |
|
|
|
To access the contents, click the chapter and section titles.
Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
Underflow errors are easy to overlook. You must be sure you consider variables with both large positive and negative values. If it is easy to determine what parameter values will produce errors, use Debug.Assert or Stop statements to verify that the values are acceptable. Use an On Error statement to catch the error in more complicated situations and in the compiled version of the program.
Function DoubleIt(ByVal x As Integer) As Integer
Debug.Assert (x >= -16384) And (x <= 16383)
DoubleIt = 2 * x
End Function
Watch for Divide by 0Watch for expressions that could cause a divide-by-0 error. If an expression includes division, check the denominator to see if can ever be 0. Use Debug.Assert, Stop, and On Error statements to prevent the routine from crashing.
Function Invert(ByVal x As Integer) As Integer
Debug.Assert x <> 0
Invert = 1 \ x
End Function
Be Aware of Argument PromotionBe certain you understand how the types of variables change when they are passed to routines or used in expressions. Use parentheses and data type conversion functions to force Visual Basic to handle the values as you intend. Think about how variable promotion can interact with the other guidelines discussed in this chapter. For example, after the following code runs, it looks as if x and y should have the same value. However, when the program reaches the statement y = 0#, Visual Basic promotes y to the double data type. During the For loop, y retains more precision than x, which is only a single. At the end of the loop, x has the value 9.999999 while y has the value 10.0000004172325. These values are not exactly equal, so the message box never appears.
Private Sub PromotionProblem()
Dim x As Single
Dim y As Variant
Dim dx As Single
Dim i As Integer
dx = 10 / 17
y = 0#
x = y
For i = 1 To 17
Do something with x and y.
x = x + dx
y = y + dx
Next i
If x = y Then MsgBox The values are equal.
End Sub
Do not rely on Visual Basic to behave as you expect. Make the results of expressions obvious to developers who read the code later. Avoid Error CodesThe problem with functions that return error codes is that you must remember to check them. If a routine returns an error code and the program ignores it, you will not be aware that a problem may be occurring. On the other hand, if a routine raises an error, you cannot fail to notice it. You must trap the error with an On Error statement or the program will crash. Try to use routines that always work. You do not need to handle errors that cannot arise. If you cannot use an error-proof routine, use one that raises errors when it fails instead of returning a status code. If neither of those options is available, be certain you check the functions status code. Visual Basic allows a program to treat a function as if it were a procedure if the program does not want the functions return value. For example, the LineTo API function draws a line to a specified point and returns a nonzero value if it is successful. The following code shows how a program can invoke LineTo with and without the return code.
Private Declare Function LineTo Lib gdi32 Alias LineTo _
(ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
:
Private Sub DrawLines()
Dim status As Long
Treat as a subroutine, ignoring the return code.
LineTo hdc, 100, 200
Check the return code.
status = LineTo(hdc, 200, 300)
Debug.Assert (status <> 0)
End Sub
If you use a function that returns a status code, do not ignore the code. See if the routine succeeded and take appropriate action if it did not. Dont Assume Variable SizesDo not assume variable sizes will remain the same forever. For example, do not assume integers take 4 bytes and that doubles take 8. Those values probably will not change in the near future, but stranger things have happened. At some point in the future, when most computers use 128-bit addressing, doubles could change to 16 or 32 bytes. Use the Len and LenB functions to see how large variables are if you need to know. Dont Assume Constant ValuesDo not assume constant values defined by Visual Basic will never change. In particular, do not assume that True will always have the value 1. False is likely to remain 0, but the value of True has been redefined by other languages like Pascal in the past. It could happen in Visual Basic. If you need to assign the value 0 or 1 to a variable depending on the results of a Boolean expression, use an If statement, not a simple assignment.
Dim X As Integer
X = (A = B) Dont use this method.
If (A = B) Then Use this method instead.
X = -1
Else
X = 0
End If
Self-TestProgram Bad8 violates several of the guidelines presented in this chapter. The program, shown in Figure 8.1, presents a sorted list of numbers. Enter a number and click the Search button to make the program try to find the number in the list.
Unfortunately, program Bad8 practically never finds the correct number. In fact, it does not even correctly generate a sorted list. Some of the numbers are not in sorted order. If the program obeyed all of the guidelines described in this chapter, it would not have these problems.
Option Explicit
The list of values.
Private Const NUM_VALUES = 50
Private Values(1 To NUM_VALUES) As Variant
Initialize the data.
Private Sub Form_Load()
InitializeData
End Sub
Create some random data.
Private Sub InitializeData()
Dim i As Integer
Dim last_value As Integer The last value assigned.
Dim txt As String
Randomize
Initialize the random numbers with each
value slightly bigger than the previous one.
last_value = 10
For i = 1 To NUM_VALUES
Values(i) = last_value + Rnd + 0.01
last_value = Values(i)
Next i
Display the values.
For i = 1 To NUM_VALUES
txt = txt & Format$(i, @@) & : & _
Format$(Values(i), 0.000) & vbCrLf
Next i
txtValues.Text = txt
End Sub
Search for the target.
Private Sub CmdSearch_Click()
Dim position As Integer
position = LinearSearch(Values, txtTarget.Text)
If position < 1 Then
lblPosition.Caption = Not found
Else
lblPosition.Caption = Format$(position)
End If
End Sub
Locate a target item using linear search. If the
target is not found, return 1 less than the
smallest array index.
Public Function LinearSearch(list() As Variant, _
target As Variant) As Integer
Dim i As Integer
For i = LBound(list) To UBound(list)
See if we found the target.
If list(i) = target Then
LinearSearch = i
Exit Function
End If
If the values are too big, we passed
where it should be so its not here.
If list(i) > target Then Exit For
Next i
End Function
|
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|